home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / preccx / prccx240.lha / cc.c < prev    next >
Text File  |  1992-08-21  |  4KB  |  231 lines

  1. /*              
  2.    parser suite - and / or / nothing / something  parsers
  3.  
  4.    parser = [token] -> ([token],status)
  5.     
  6.    implemented as sideeffecting on [token], returns status.
  7. */
  8.  
  9. # include "cc.h"
  10.  
  11. STATUS  p_andparse0 (p, q)
  12. /*
  13. Serial composition of parsers. Does
  14. first p then q. Put p's instructions on the
  15. top of the program stack, then layer q's above it.
  16.  
  17. This version has full rewind of the input stream on
  18. failure, but this can be altered to single token
  19. lookahead by deleting the line of code marked.
  20. */
  21. PARSER  p, q;
  22. {
  23.     static status tok;    /* why can't this be static? */
  24.  
  25.     MARK;
  26.  
  27.     tok = p ();
  28.     if (BADSTATUS (tok)){    /* error */
  29.             RELEASE;
  30.         return tok;
  31.      }
  32.     tok = q ();
  33.     if (BADSTATUS (tok))    /* error */
  34.     {
  35.         REWIND;        /* remove this line for 1-token LA parsing */
  36.         return tok;
  37.     }
  38.  
  39.     pushDECR;
  40.     RELEASE;
  41.     return tok;    /* succeed */
  42. }
  43.  
  44.  
  45. STATUS  p_orparse0 (p, q)
  46. /*
  47. alternate composition of parsers. Tries p first,
  48. and if it doesnt work, tries q. Code corresponding
  49. to the successful parse is placed on the program stack.
  50. If both fail, the routine relies on p and q's auto-rewind
  51. mechanisms to do the rewind for it.
  52. */
  53. PARSER  p, q;
  54. {
  55.     static status  tok;     /* I don't see why this can't be static */
  56.  
  57.     tok = p ();
  58.  
  59.     if (BADSTATUS (tok))    /* error */
  60.         tok = q ();    /* retry */
  61.  
  62.     return tok;        /* whatever */
  63. }
  64.  
  65. STATUS p_many0 (p)
  66. /*
  67. parser which tries p any number of times
  68. until p fails, but returns success anyhow.
  69. */
  70. PARSER p;
  71. {
  72.     int repeat = 0;
  73.  
  74.     while (GOODSTATUS(p ()))
  75.         repeat++;
  76.  
  77.     switch(repeat){
  78.     case 0: pushINCR; break;
  79.     case 1: break;
  80.     default:pushMANIP(-(repeat-1)); break;
  81.     }
  82.  
  83.     return (SUCCESS);
  84. }
  85.  
  86. STATUS p_iter0 (repeat, p)
  87. /*
  88. parser which tries p repeat number of times exactly
  89. */
  90. PARSER p;
  91. int repeat;
  92. {
  93.     static int k;
  94.     static status tok;
  95.     MARK;
  96.  
  97.     k = repeat;
  98.  
  99.     while (k-->0) {
  100.         tok = p ();
  101.         if (BADSTATUS(tok)) {
  102.             REWIND;
  103.             return tok;
  104.         }
  105.     }
  106.  
  107.     switch(repeat){
  108.     case 0: pushINCR; break;
  109.     case 1: break;
  110.     default:pushMANIP(-(repeat-1)); break;
  111.     }
  112.  
  113.     RELEASE;
  114.     return tok;
  115. }
  116.  
  117.  
  118. STATUS  p_some0 (p)
  119. /*
  120. At least one repetition of parser p
  121. */
  122. PARSER p;
  123. {
  124.     status tok;
  125.  
  126.     tok = p ();
  127.     if (GOODSTATUS(tok)){
  128.  
  129.         tok = p_many0 (p);
  130.         pushDECR; /* bound to succeed */
  131.         return(tok);
  132.     }
  133.  
  134.     return tok;
  135. }
  136.  
  137. STATUS p_option0 (p)
  138. /* optionally p */
  139. PARSER p;
  140. {
  141.     static status tok;
  142.  
  143.     tok = p();
  144.     if (GOODSTATUS(tok))
  145.         return tok;
  146.  
  147.     pushINCR;
  148.     return(SUCCESS);
  149. }
  150.  
  151.  
  152. STATUS p_range0 (p)
  153. /*
  154. checks whether *pstr satisfies predicate p.
  155. p must take a TOKEN as arg. That is a mistake. It should be
  156. an int (a PARAM).
  157. */
  158. PREDICATE *p;
  159. {
  160.     VALUE v;
  161.  
  162.     if ((*p) (*pstr))
  163.     {
  164.         v = lvbuff[pstr-buffer];
  165.         MOVEON;
  166.         pushVALUE(v);
  167.         return (OK(v));
  168.     }
  169.     return (FAILURE);
  170. }
  171.  
  172. STATUS p_attach (p,f)
  173. PARSER p;
  174. ACTION f;
  175. {
  176.     static status tok;
  177.  
  178.     tok = p ();
  179.     if (GOODSTATUS(tok)) {
  180.  
  181.         pushACTION(f);
  182.         return tok;
  183.     }
  184.  
  185.     return tok;
  186.  
  187. }
  188.  
  189. STATUS p_prepend (f,p)
  190. PARSER p;
  191. ACTION f;
  192. {
  193.     static status tok;
  194.     MARK;
  195.  
  196.     pushACTION(f);
  197.  
  198.     tok = p ();
  199.     if (GOODSTATUS(tok)) {
  200.         RELEASE;
  201.     return tok;
  202.     }
  203.  
  204.     REWIND;
  205.  
  206.     return tok;
  207. }
  208.  
  209.  
  210. STATUS  p_hidden0 (p)
  211. PARSER p;
  212. /*
  213. parser which tries p, but doesnt moveon, just reports the result
  214. of p.
  215. */
  216. {
  217.     static status tok;
  218.     MARK;
  219.  
  220.  
  221.     tok = p ();
  222.         
  223.     REWIND;
  224.  
  225.     if(GOODSTATUS(tok)) {   /* we have to show we were here to keep in V(n) step */
  226.            pushVALUE(tok);
  227.            return tok;
  228.     }
  229.     return tok;
  230. }
  231.